import os
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np
import csv


class UpStreamAnalysis:
    def __init__(self):
        self.g = nx.DiGraph()
        folder = os.path.exists("./UpData/top10")
        if not folder:  # 判断是否存在文件夹如果不存在则创建为文件夹
            os.makedirs("./UpData/top10")
        folder = os.path.exists("./UpData/pics")
        if not folder:  # 判断是否存在文件夹如果不存在则创建为文件夹
            os.makedirs("./UpData/pics")

    def insert_data(self, nodelist):
        """
        插入图的数据
        :param nodelist: node列表
        """
        self.g.clear()
        for node in nodelist:
            self.g.add_node(node.name)
        for node in nodelist:
            for enter in node.children:
                if self.g.has_edge(enter.name, node.name): break
                self.g.add_edge(enter.name, node.name)
            for out in node.req:
                if self.g.has_edge(node.name, out.name): break
                self.g.add_edge(node.name, out.name)
        print("*******Insert finish!*******")

    # 打印边
    def show(self):
        for e in self.g.edges:
            print(e)

    def showInDegree(self, nodelist):
        self.showPlt(nodelist, 'in')
        k = sorted(nodelist, key=lambda x:len(x.children), reverse=True)
        self.getTable2(k, './UpData/top10/in_degree_Table.csv', 'in')

    def showOutDegree(self, nodelist):
        self.showPlt(nodelist, 'out')
        k = sorted(nodelist, key=lambda x: len(x.req), reverse=True)
        self.getTable2(k, './UpData/top10/out_degree_Table.csv', 'out')

    def showPlt(self, nodelist, kind):
        x = np.linspace(0, 700, num=701)
        y = 0
        yy = []
        for i in range(701):
            for n in nodelist:
                if kind == 'in':
                    if i == len(n.children):
                        y = y + 1
                else:
                    if i == len(n.req):
                        y = y + 1
            if y == 0:
                yy.append(-100)
            else:
                yy.append(y)
            y = 0
        plt.ylabel('value')
        if kind == 'in':
            plt.xlabel('InDegree')
        else:
            plt.xlabel('OutDegree')
        plt.plot(x, yy, 'r.')
        plt.axis([0, 700, 0, 1000])
        if kind == 'in':
            plt.savefig('./UpData/pics/InDegree.png')
        else:
            plt.savefig('./UpData/pics/OutDegree.png')
        plt.show()

    # 计算betweenness centray
    def betweenness(self):
        centray = nx.degree_centrality(self.g)
        d = sorted(centray.items(), key=lambda x: x[1])
        now, num = -1, 0
        x = []
        y = []
        for i in d:
            if now != i[1]:
                x.append(now)
                y.append(num)
                now = i[1]
                num = 1
            if now == i[1]:
                num = num + 1
        plt.xlabel('betweenness_centray')
        plt.ylabel('value')
        plt.plot(x, y, 'r.')
        plt.axis([-0.05, 0.10, 0, 1500])
        plt.savefig('./UpData/pics/betweenness.png')
        plt.show()
        self.getTable(centray, './UpData/top10/betweenness_centray_Table.csv')

    # 聚类分析
    def clustering(self):
        close = nx.clustering(self.g)
        d = sorted(close.items(), key=lambda x: x[1])
        now, num = -1, 0
        x = []
        y = []
        for i in d:
            if now != i[1]:
                x.append(now)
                y.append(num)
                now = i[1]
                num = 1
            if now == i[1]:
                num = num + 1
        plt.xlabel('clustering')
        plt.ylabel('value')
        plt.plot(x, y, 'r.')
        plt.axis([-1, 2, 0, 5000])
        plt.savefig('./UpData/pics/clustering.png')
        plt.show()
        self.getTable(close, './UpData/top10/clutering_Table.csv')

    def getTable(self, d, path):
        # 输出be和clu的表格
        d = sorted(d.items(), key=lambda x: x[1], reverse=True)
        with open(path, 'w', newline='') as csv_file:
            writer = csv.writer(csv_file)
            i = 0
            for k in d:
                if i == 9:
                    break
                writer.writerow([k[0], k[1]])
                i = i + 1

    def getTable2(self, d, path, kind):
        # 输出出度和入读的表格
        folder = os.path.isfile(path)
        with open(path, 'w', newline='') as csv_file:
            writer = csv.writer(csv_file)
            i = 0
            for k in d:
                if i == 9:
                    break
                if kind == 'in':
                    writer.writerow([k.name, len(k.children)])
                else:
                    writer.writerow([k.name, len(k.req)])
                i = i + 1